#include "dirStack.h"
#include "jiekou.h"
#include "main_header.h"
#include "plog.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>

int recvn(int netfd, void *buf, int length) {
  char *p = (char *)buf;
  int total = 0;

  while (total < length) {
    int res = recv(netfd, total + p, length - total, 0);
    total += res;
  }
  return total;
}
int recv_command(int netfd) { // 接收标志
  train_t train;
  // char command[1024];
  //  bzero(command_name,sizeof(command_name));
  bzero(train.data, sizeof(train.data));
  bzero(&train.length, sizeof(train.length));
  recvn(netfd, &train.type, sizeof(train.type));

  printf("服务端收到 type = %d\n", train.type);
  LOG_INFO("服务端收到 type = %d\n", train.type);
  return train.type;
}

int send_Feedback_Good(int netfd) { // 发送反馈,需要获取函数的返回值，才能继续写
  train_t train;
  char buf[1024] = "执行成功";
  memcpy(train.data, buf, strlen(buf));
  train.length = strlen(buf);
  send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
  send(netfd, train.data, train.length, MSG_NOSIGNAL);
  return 0;
}

int send_Feedback_bad(int netfd) { // 发送反馈,需要获取函数的返回值，才能继续写
  train_t train;
  char buf[1024] = "失败";
  memcpy(train.data, buf, strlen(buf));
  train.length = strlen(buf);
  send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
  send(netfd, train.data, train.length, MSG_NOSIGNAL);
  return 0;
}

void *work(void *arg) {
  Main_thread *work = (Main_thread *)arg;
  train_t train;
  user_t user;
  file_t file;
  dirStack_t dirStack;
  initStack(&dirStack);
  while (1) {
    pthread_mutex_lock(&work->mutex);
    while (work->queue.size <= 0) {
      pthread_cond_wait(&work->cond, &work->mutex);
    }
    int netfd = work->queue.head->val;
    printf("one worker get the job,from netfd  == %d\n", work->queue.head->val);
    LOG_INFO("one worker get the job,from netfd  == %d\n", work->queue.head->val);
    delete_head(&work->queue);
    MYSQL *db = initDB("localhost", "root", "691163", "zjx");
    ERROR_CHECK(db, NULL, "InitDb");
    pthread_mutex_unlock(&work->mutex);
    while(1)
    {
    recvn(netfd, &train.length, sizeof(train.length));
    if (train.length == 0) {

      int flag = userRegister(db, netfd, &user);
      char sql1[4096] = {0};
      snprintf(
          sql1, sizeof(sql1),
          "insert into file (username,filename,parent_id,type,path,is_deleted) "
          "values('%s','/',-1,'d','/',0)",
          user.user[0].username);
      const char *sql2 = sql1;
      execDB(sql2, db);
      bzero(sql1, sizeof(sql1));
      snprintf(sql1, sizeof(sql1),
               "select id from file where username='%s' and path='%s' and "
               "is_deleted=0",
               user.user[0].username, "/");
      const char *sql3 = sql1;
      selectFile1(sql3, db, &file);
      pushStack(&dirStack, file.file[0].id);
      //printStack(&dirStack);
      if (flag == -1) {
        continue;
      }
    } else {
      int flag = userLogin(db, netfd, &user);
      char sql5[4096] = {0};
      snprintf(sql5, sizeof(sql5),
               "select id from file where username='%s' and path='%s' and "
               "is_deleted=0",
               user.user[0].username, "/");
      const char *sql3 = sql5;
      selectFile1(sql3, db, &file);
      pushStack(&dirStack, file.file[0].id);
      //printStack(&dirStack);
      if (flag == -1) {
        continue;
      }
      else {
      goto end;
      }
    }
  }
  end:
  printf("登录成功\n");
  LOG_INFO("登录成功\n");
    char absolute_path[] = "/home/dianfen/wangpan3qi";
    // 函数调用；；；；；
    DIR *dirp = opendir(absolute_path);
    char finPath[4096] = {0};
    char obs[4096] = "/home/dianfen/wangpan3qi";
    while (1) {
      int get_command = recv_command(netfd);
      if (get_command < 0) {
        printf("recv quit\n");
        LOG_INFO("recv quit\n");
        close(netfd);
        exit(-1);
      }
      printf("----------------%d\n", get_command);
      LOG_INFO("----------------%d\n", get_command);
      bzero(train.data, sizeof(train.data));
      bzero(&train.length, sizeof(train.length));
      char command[1024];
      bzero(command, sizeof(command));
      char arr[4096] = {0};
      char app[4096] = {0};
      char aii[4096] = {0};
      char result[4096] = {0};
      switch (get_command) {
        if (get_command < 0) {
          close(netfd);
          exit(-1);
        }

      case 0:
        recvn(netfd, &train.length, sizeof(train.length));
        recvn(netfd, train.data, train.length);
        //printf("%s\n",train.data);
        strcpy(command, train.data);
        //memcpy(command, train.data, train.length);
        //printf("%s\n",command);
        command[train.length] = '\0';
        bzero(result, sizeof(result));
        use_cd(&dirStack, db, command, user.user[0].username, result);
        //printf("%s\n", result);
        // printf("finish cd\n");
        //train.length = strlen(result);
        //send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        //send(netfd, result, train.length, MSG_NOSIGNAL);
        break;
      case 1:
        ls(&dirStack, db, result);
        // printf("finish ls %s\n",arr);
        train.length = strlen(result);
        printf("%s\n",result);
        LOG_INFO("%s\n",result);
        send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        send(netfd, result, train.length, MSG_NOSIGNAL);
        break;
      case 2:
        // PUTS
        user_puts(&dirStack, user.user[0].username, netfd, db, absolute_path,
                  &file);
        break;
        printf("finish puts\n");
        LOG_INFO("finish puts\n");
        // use_puts(netfd);
      case 3:
        recvn(netfd, &train.length, sizeof(train.length));
        recvn(netfd, train.data, train.length);
        memcpy(command, train.data, train.length);
        command[train.length] = '\0';
        use_gets( netfd, command,&file);
        printf("finish gets\n");
        LOG_INFO("finish gets\n");
        break;
      case 4:
        command[train.length] = '\0';
        use_remove(&dirStack, netfd, db, user.user[0].username);
        printf("finish remove\n");
        LOG_INFO("finish remove\n");
        break;
      case 5:
        bzero(train.data, sizeof(train.data));
        bzero(result, sizeof(result));
        use_pwd(&dirStack, db, result);
        train.length = strlen(result);
        strcpy(train.data, result);
        printf("%s\n", result);
        send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        send(netfd, train.data, train.length, MSG_NOSIGNAL);
        break;
      case 6:
        bzero(app, sizeof(app));
        bzero(aii, sizeof(aii));
        recvn(netfd, &train.length, sizeof(train.length));
        recvn(netfd, train.data, train.length);
        memcpy(app, train.data, strlen(train.data));
        makedir(&dirStack, db, user.user[0].username, app, result);
        train.length = strlen(result);
        send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        send(netfd, result, train.length, MSG_NOSIGNAL);
        printf("%s\n", result);
        LOG_INFO("%s\n",result);
        printf("finish mkdir\n");
        LOG_INFO("finish mkdir\n");
        break;
      case 7:
        recvn(netfd, &train.length, sizeof(train.length));
        recvn(netfd, train.data, train.length);
        memcpy(command, train.data, train.length);
        command[train.length] = '\0';
        removeDir(&dirStack, db, user.user[0].username, command, result);
        train.length = strlen(result);
        send(netfd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
        send(netfd, result, train.length, MSG_NOSIGNAL);
        printf("finish rmdir\n");
        LOG_INFO("finish rmdir\n");
        printf("%s\n", result);
        LOG_INFO("%s\n", result);
        break;
      case 8:
        printf("finish failure\n");
        LOG_INFO("finish failure\n");
        break;
      }
    }
  }
}
int makeworker(Main_thread *m_thread) {
  for (int i = 0; i < m_thread->arr.workNum; i++) {
    pthread_create(&m_thread->arr.Arr[i], NULL, work, m_thread);
  }
  return 0;
}
